﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcCaja.Core.Interfaces;
using Chilis.Caja.Data.Models;

namespace MvcCaja.Core
{
    public class PagoService : IPagoService
    {

        public List<Pago> obtenerOrden(string sCodigoOrden)
        {
            ModelDataContext db = new ModelDataContext();

            return (from n in db.Pago
                    where n.IdOrden.Equals(sCodigoOrden)
                    select n).ToList<Pago>();
        }

        public List<Pago> Movimientos(DateTime fecIni, DateTime fecFin, string caja, string empleado)
        {
            ModelDataContext db = new ModelDataContext();

            //var result = from n in db.Pagos
            //                group n by n.CodigoOrden into g
            //                select new {
            //                    CodigoOrden = g.Key,
            //                    NumeroCuenta = "",
            //                    TipoComprobante = "",
            //                    Total = g.Sum(x => x.Total)
            //                };
            //return result.ToList<Pago>;


            return (from n in db.Pago
                    join mc in db.MovimientoCaja
                    on new { n.IdOrden, n.NumeroCuenta } equals new {mc.IdOrden, mc.NumeroCuenta}
                    where
                    mc.IdCaja.Contains(caja) && mc.IdCajero.Contains(empleado) &&
                    n.FechaHoraEmision.Date >= fecIni.Date && n.FechaHoraEmision.Date <= fecFin.Date &&
                    n.FechaAnulacion == null
                    select n).Distinct().ToList<Pago>();
        }

        public Pago obtener(string sCodigoOrden, int iNumeroCuenta)
        {
            ModelDataContext db = new ModelDataContext();

            return (from n in db.Pago
                    where n.IdOrden.Equals(sCodigoOrden) && n.NumeroCuenta.Equals(iNumeroCuenta)
                    select n).First<Pago>();
        }

        public void insertar(String sCodigoOrden, int iNumeroCuenta, String sCodigoCaja, String sCodigoTurno, String sCodigoCajero, Decimal dMontoSoles, Decimal dMontoDolares, Decimal dMontoVisa, Decimal dMontoMastercard, String sTipoComprobante, String sRUC, String sNombre, String sDireccion, Boolean bDetalle, Decimal dTipoCambio, Decimal dVuelto, String sNumeroVisa, String sNumeroMastercard, String sCupon)
        {
            ModelDataContext db = new ModelDataContext();

            Pago oPago = new Pago();

            Decimal dTotal = 0;

            DateTime dAhora = DateTime.Now;

            Serie oSerie = (from n in db.Serie
                            where n.CodigoCaja.Equals(sCodigoCaja)
                            select n).First<Serie>();

            
            oSerie.Correlativo += 1;

            oPago.IdOrden = sCodigoOrden;
            oPago.NumeroCuenta = iNumeroCuenta;
            oPago.TipoComprobante = sTipoComprobante;
            oPago.NumeroComprobante = String.Format("{0}-{1}",oSerie.Serie1.ToString("00#"),oSerie.Correlativo.ToString("00000#")) ;

            if (sCupon == string.Empty)
                oPago.IdCupon = null;
            else
            {
                oPago.IdCupon = sCupon;

                Cupon oCupon = (from n in db.Cupon
                                where n.IdCupon.Equals(sCupon)
                                select n).First<Cupon>();

                oCupon.CondicionesCupon = "Consumido";
            }
            
            oPago.FechaHoraEmision = dAhora;
            oPago.MostrarDetallePago = bDetalle;

            if (dMontoSoles > 0)
            {
                MovimientoCaja oMovimientoCajaSoles = new MovimientoCaja();

                oMovimientoCajaSoles.IdCaja = sCodigoCaja;
                oMovimientoCajaSoles.IdTurno = sCodigoTurno;
                oMovimientoCajaSoles.IdCajero = sCodigoCajero;
                oMovimientoCajaSoles.TipoMovimiento = "Soles";
                oMovimientoCajaSoles.FechaHoraMovimiento = dAhora;
                oMovimientoCajaSoles.MontoMovimiento = dMontoSoles;

                dTotal += dMontoSoles;
                
                oPago.MovimientoCaja.Add(oMovimientoCajaSoles);
            }

            if (dMontoDolares > 0)
            {
                MovimientoCaja oMovimientoCajaDolares = new MovimientoCaja();

                oMovimientoCajaDolares.IdCaja= sCodigoCaja;
                oMovimientoCajaDolares.IdTurno = sCodigoTurno;
                oMovimientoCajaDolares.IdCajero = sCodigoCajero;
                oMovimientoCajaDolares.TipoMovimiento = "Dólares";
                oMovimientoCajaDolares.FechaHoraMovimiento = dAhora;
                oMovimientoCajaDolares.MontoMovimiento = dMontoDolares;

                dTotal += dMontoDolares * dTipoCambio;

                oPago.MovimientoCaja.Add(oMovimientoCajaDolares);
            }

            if (dMontoVisa > 0)
            {
                MovimientoCaja oMovimientoCajaVisa = new MovimientoCaja();

                oMovimientoCajaVisa.IdCaja = sCodigoCaja;
                oMovimientoCajaVisa.IdTurno = sCodigoTurno;
                oMovimientoCajaVisa.IdCajero = sCodigoCajero;
                oMovimientoCajaVisa.TipoMovimiento = "Visa";
                oMovimientoCajaVisa.FechaHoraMovimiento = dAhora;
                oMovimientoCajaVisa.MontoMovimiento = dMontoVisa;
                oMovimientoCajaVisa.NumeroTarjeta = sNumeroVisa;

                dTotal += dMontoVisa;

                oPago.MovimientoCaja.Add(oMovimientoCajaVisa);
            }

            if (dMontoMastercard > 0)
            {
                MovimientoCaja oMovimientoCajaMastercard = new MovimientoCaja();

                oMovimientoCajaMastercard.IdCaja = sCodigoCaja;
                oMovimientoCajaMastercard.IdTurno = sCodigoTurno;
                oMovimientoCajaMastercard.IdCajero = sCodigoCajero;
                oMovimientoCajaMastercard.TipoMovimiento = "Mastercard";
                oMovimientoCajaMastercard.FechaHoraMovimiento = dAhora;
                oMovimientoCajaMastercard.MontoMovimiento = dMontoMastercard;
                oMovimientoCajaMastercard.NumeroTarjeta = sNumeroMastercard;

                dTotal += dMontoMastercard;

                oPago.MovimientoCaja.Add(oMovimientoCajaMastercard);
            }

            if (dVuelto > 0)
            {
                MovimientoCaja oMovimientoCajaVuelto = new MovimientoCaja();

                oMovimientoCajaVuelto.IdCaja = sCodigoCaja;
                oMovimientoCajaVuelto.IdTurno = sCodigoTurno;
                oMovimientoCajaVuelto.IdCajero = sCodigoCajero;
                oMovimientoCajaVuelto.TipoMovimiento = "Vuelto";
                oMovimientoCajaVuelto.FechaHoraMovimiento = dAhora;
                oMovimientoCajaVuelto.MontoMovimiento = -dVuelto;

                dTotal -= dVuelto;

                oPago.MovimientoCaja.Add(oMovimientoCajaVuelto);
            }

            oPago.Total = dTotal;

            if (sTipoComprobante.Equals("Factura"))
            {
                Cliente oCliente = null;

                List<Cliente> lstCliente = (from n in db.Cliente
                                            where n.TipoDocumento.Equals("RUC") && n.NumeroDocumento.Equals(sRUC)
                                            select n).ToList<Cliente>();
                if (lstCliente.Count > 0)
                {
                    oCliente = lstCliente[0];
                    oCliente.RazonSocial = sNombre;
                }
                else
                {

                    oCliente = new Cliente();

                    //oCliente.IdCliente = iCodigoMaximo + 1; //"C" + (iCodigoMaximo + 1).ToString("00000000#");
                    //oCliente.TipoCliente = "Juridico";
                    oCliente.TipoDocumento = "RUC";
                    oCliente.NumeroDocumento = sRUC;
                    oCliente.Nombres = "";
                    oCliente.ApellidoPaterno = "";
                    oCliente.RazonSocial = sNombre;
                    
                    db.Cliente.InsertOnSubmit(oCliente);

                    db.SubmitChanges();
                }

                Cuenta oCuenta = (from n in db.Cuenta
                                  where n.IdOrden.Equals(sCodigoOrden) && n.NumeroCuenta.Equals(iNumeroCuenta)
                                  select n).First<Cuenta>();

                oCuenta.IdCliente = oCliente.IdCliente;

            }


            db.Pago.InsertOnSubmit (oPago);

            db.SubmitChanges();


            int iCantidadCuentas = (    from n in db.Cuenta
                                        where n.IdOrden.Equals(sCodigoOrden)
                                        select n).Count();


            int iCantidadPagos = (from n in db.Pago
                                    where n.IdOrden.Equals(sCodigoOrden)
                                    select n).Count();


            if (iCantidadCuentas == iCantidadPagos)
            {
                var vMesa = ( from n in db.Mesa
                              where n.CodigoOrden.Equals(sCodigoOrden)
                              select n);

                if (vMesa.Count() > 0)
                {
                    Mesa oMesa = vMesa.First<Mesa>();

                    oMesa.CodigoOrden = null;
                    oMesa.EstadoMesa = 'L';

                    db.SubmitChanges();
                }
            }
        }

        public void eliminar(String sCodigoOrden, int iNumeroCuenta)
        {
            ModelDataContext db = new ModelDataContext();

            List<MovimientoCaja> lstMovimientoCaja = (from n in db.MovimientoCaja
                                                      where n.IdOrden.Equals(sCodigoOrden) && n.NumeroCuenta.Equals(iNumeroCuenta)
                                                      select n).ToList<MovimientoCaja>();

            foreach (MovimientoCaja oMovimientoCaja in lstMovimientoCaja)
                db.MovimientoCaja.DeleteOnSubmit(oMovimientoCaja);


            Pago oPago = (from n in db.Pago
                          where n.IdOrden.Equals(sCodigoOrden) && n.NumeroCuenta.Equals(iNumeroCuenta)
                          select n).First<Pago>();

            db.Pago.DeleteOnSubmit(oPago);


            //habilitar mesa si se elimina pago
            var vMesa = (from n in db.Mesa
                         where n.CodigoOrden.Equals(sCodigoOrden)
                         select n);

            if (vMesa.Count() > 0)
            {
                Mesa oMesa = vMesa.First<Mesa>();

                oMesa.CodigoOrden = sCodigoOrden;
                oMesa.EstadoMesa = 'O';
            }

            db.SubmitChanges();
        }


        public string anular(String sCodigoOrden, String sCodigoAdministrador, String sConcepto)
        {
            try
            {
                ModelDataContext db = new ModelDataContext();

                List<Pago> ListPago = (from n in db.Pago
                              where n.IdOrden.Equals(sCodigoOrden)
                              select n).ToList<Pago>();

                foreach (Pago oPago in ListPago) {
                    oPago.FechaAnulacion = DateTime.Now;
                    oPago.ConceptoAnulacion = sConcepto;
                    oPago.CodigoAdministrador = sCodigoAdministrador;                    
                }
                db.SubmitChanges();

                return "success";
            }
            catch (Exception ex) {
                return ex.Message;
            }
        }
    }
}
